<?php

/*******************************************************************************
 * 为调试信息服务，增加一个锚点定位
 *******************************************************************************/
function anchor($name, $title = ''){
	$title = empty($title) ? "@{$name}@" : trim($title);
	return "<a name=\"{$name}\">{$title}</a>";
}

/*******************************************************************************
 * 读取语言
 *******************************************************************************/
function lang($lang_key, $force = true){
	return isset($GLOBALS['__l'][$lang_key]) ? $GLOBALS['__l'][$lang_key] : ($force ? $lang_key : '');
}

/********************************************************************************
 * 格式化
 ********************************************************************************/
function fdate($timestamp = 0, $now = false){
	if($timestamp == 0){
		if($now){
			return date('Y-m-d');
		}else{
			return '--';
		}
	}else{
		return date('Y-m-d', $timestamp);
	}
}

function ftime($timestamp = 0, $now = false){
	if(empty($timestamp)){
		if($now){
			return date('Y-m-d H:i:s');
		}else{
			return '--';
		}
	}else{
		return date('Y-m-d H:i:s', $timestamp);
	}
}

function utime($addtime, $updatetime = 0){
	if($updatetime > 0){
		return date('Y-m-d H:i:s', $updatetime); 
	}else{
		return date('Y-m-d H:i:s', $addtime);
	}
}

function udate($addtime, $updatetime = 0){
	if($updatetime > 0){
		return date('Y-m-d', $updatetime); 
	}else{
		return date('Y-m-d', $addtime);
	}
}

/**
 * PHP实现 Javascript 的 escape()
 * http://www.phpchina.com/html/91/n-1091.html
 */
 
/*function escape($str){ 
	preg_match_all("/[\xc2-\xdf][\x80-\xbf]+|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}|[\x01-\x7f]+/e", $str, $r); 
	//匹配utf-8字符， 
	$str = $r[0]; 
	$__len = count($str); 
	for($i=0; $i < $__len; $i++){ 
		$value = ord($str[$i][0]); 
		if($value < 223){ 
			$str[$i] = rawurlencode(utf8_decode($str[$i])); 
			//先将utf8编码转换为ISO-8859-1编码的单字节字符，urlencode单字节字符. 
			//utf8_decode()的作用相当于iconv("UTF-8","CP1252",$v)。 
		}else{ 
			$str[$i] = "%u".strtoupper(bin2hex(iconv("UTF-8","UCS-2",$str[$i]))); 
		} 
	} 
	return join("",$str); 
}*/

/*function unescape($str){ 
	$ret = '';
	$len = strlen($str);
	for ($i = 0; $i < $len; $i++){
		if ($str[$i] == '%' && $str[$i+1] == 'u'){
			$val = hexdec(substr($str, $i+2, 4));
			if ($val < 0x7f) 
				$ret .= chr($val);
			else if($val < 0x800)
				$ret .= chr(0xc0|($val>>6)).chr(0x80|($val&0x3f));
			else
				$ret .= chr(0xe0|($val>>12)).chr(0x80|(($val>>6)&0x3f)).chr(0x80|($val&0x3f));
			$i += 5;
		}else if ($str[$i] == '%'){ $ret .= urldecode(substr($str, $i, 3));
				$i += 2;
		} else
			$ret .= $str[$i];
	}
	return $ret;
}*/

function check($var, $val = 1){
	if(isset($val) && $var == $val){
		return true;
	}
	return false;
}

// 用新数组更新数组值
function array_update(& $arr, $update){
	foreach($update as $key => $val){
		$arr[$key] = $val;
	}
	return $arr;
}

// 将 Object 转换成 Array
function std_class_object_to_array($stdclassobject){
    $_array = is_object($stdclassobject) ? get_object_vars($stdclassobject) : $stdclassobject;

    foreach($_array as $key => $value){
        $value = (is_array($value) || is_object($value)) ? std_class_object_to_array($value) : $value;
        $array[$key] = $value;
    }

    return $array;
}

# 判断是否是序列化字符串
function is_serialized($data){
 	$data = trim($data);
 	if ('N;' == $data)
 		return true;
 	if (!preg_match('/^([adObis]):/', $data, $badions))
 		return false;
 	switch ($badions[1]){
 		case 'a' :
 		case 'O' :
 		case 's' :
 			if (preg_match("/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data))
 				return true;
 			break;
 		case 'b' :
 		case 'i' :
 		case 'd' :
 			if (preg_match("/^{$badions[1]}:[0-9.E-]+;\$/", $data))
 				return true;
 			break;
 	}
 	return false;
 }

// function get_microtime(){	// 废弃	return microtime(true);
// 	list($usec, $sec) = explode(' ', microtime());
// 	return((float)$usec + (float)$sec);
// }

/*******************************************************************************
 * 混淆密码
 *******************************************************************************/
function mix_words($words){
	$sitekey = str_split(str_replace('-', '', SITE_KEY));
	$len = count($sitekey);

	$words = str_split($words);
	$nword = array();
	foreach($words as $word){
		$pos = ord($word) % $len;
		$nword[] = $word;
		while($pos < $len){
			$nword[] = $sitekey[$pos];
			$pos *= 2;
			if($pos == 0){$pos = 3;}
		}
	}
	return implode('', $nword);
}

function get_uuid(){
	list($msec, $sec) = explode('.', microtime(true));
	return date('ymdHis') . str_replace('0.', '', substr($msec, 2, 4));
}

function get_ip(){
	if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')){
		$ip = getenv('HTTP_CLIENT_IP');
	}
	elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')){
		$ip = getenv('HTTP_X_FORWARDED_FOR');
	}
	elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')){
		$ip = getenv('REMOTE_ADDR');
	}
	elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')){
		$ip = $_SERVER['REMOTE_ADDR'];
	}
	return preg_match("/[\d\.]{7,15}/", $ip, $matches) ? $matches[0] : 'unknown';
}

/********************************************************************************
 * 简写EA
********************************************************************************/

function ea_set($key, $value, $ttl = 0){
	return false;
	if(function_exists('eaccelerator_put')){
		$ttl = $ttl > 0 ? $ttl : EA_TTL;
		return @eaccelerator_put(EA_PRE.$key, $value, $ttl);
	}else{
		return null;
	}
}

function ea_get($key){
	return false;
	if(function_exists('eaccelerator_get')){
		return @eaccelerator_get(EA_PRE.$key);
	}else{
		return null;
	}
}

function ea_clear($key){
	return false;
	if(function_exists('eaccelerator_rm')){
		return @eaccelerator_rm(EA_PRE.$key);
	}else{
		return true;
	}
}

// 读取语言文件
function ea_read_language($lang_setting, $filenames, $append = true){
	if(!is_array($filenames))$filenames = array($filenames);
	foreach($filenames as $filename){
		$key = md5($lang_setting['mark'].$filename);
		$_tmp_lang = ea_get($key);
		if(empty($_tmp_lang)){
			$language_filename = LNG_PTH.$lang_setting['mark']."/$filename.lang.php";
			if(file_exists($language_filename)){
				$_tmp_lang = include_once $language_filename;
				ea_set($key, $_tmp_lang);
			}
		}
		if(!is_array($_tmp_lang))$_tmp_lang = array();
		if($append && is_array($GLOBALS['__l'])){
			$GLOBALS['__l'] = array_merge($GLOBALS['__l'], $_tmp_lang);
		}else{
			$GLOBALS['__l'] = $_tmp_lang;
		}
	}
	return $GLOBALS['__l'];
}

/********************************************************************************
 * 参考 PHPCMS 加入文件缓存读写函数
 ********************************************************************************/

function cache_read($file, $path = '', $ea_cache = true){
	if($path == ''){$path = dirname($file);}
	if($path == '' || $path == '.'){$path = CAC_PTH;}
	if(substr($path, -1, 1) != '/')$path .= '/';
	$cachefile = $path.basename($file);
	// 从缓存读取
	if($ea_cache == true){
		$key = md5($cachefile);
		$re = ea_get($key);
	}
	if(empty($re) && file_exists($cachefile)){
		$re = @include $cachefile;
		if($ea_cache == true)ea_set($key, $re);
	}
	
	// 调试信息
	if(
		(isset($_GET['cache_read']) && $_GET['cache_read'] == 'yes') || 
		(
			!in_array($file, array('cls_arr.php', 'styles.php','languages.php', 'econfigs.php',)) &&
			strpos($file, 'role_') === false && 
			strpos($file, 'manager_') === false
		)
	){
		
		if(defined('DEBUG_PR') && DEBUG_PR == true){
			$debug_info = array(
				'trace'	=> stack_trace(),
				'file'	=> $cachefile,
				'data'	=> $re,
			);
			if(isset($debug_info['trace'][1])){	// 默认读取的内容不打印
				$file = basename(trim(array_shift(explode('#', $debug_info['trace'][1]))));
			}else{
				$file = basename(trim(array_shift(explode('#', $debug_info['trace'][0]))));
			}
			if(!in_array($file, array('entry.php', '_config.php'))){
				$GLOBALS['debug_info'][] = $debug_info;
			}
		}
		if(defined('DEBUG_FB') && DEBUG_FB == true){
			$debug_info = empty($debug_info) ? array(
				'trace'	=> stack_trace(),
				'file'	=> $cachefile,
				'data'	=> $re,
			) : $debug_info;
			if(isset($debug_info['trace'][1])){	// 默认读取的内容不打印
				$file = basename(trim(array_shift(explode('#', $debug_info['trace'][1]))));
			}else{
				$file = basename(trim(array_shift(explode('#', $debug_info['trace'][0]))));
			}
			if(!in_array($file, array('entry.php', '_config.php'))){
				fb($debug_info, 'cache_read');
			}
		}
	}
	
	return $re;
}

function cache_write($file, $array, $path = ''){
	if(!is_array($array)) return false;
	$array = "<?php\r\nreturn ".var_export($array, true).";\r\n?>";
	if($path == ''){$path = dirname($file);}
	if($path == '' || $path == '.'){$path = CAC_PTH;}
	if(substr($path, -1, 1) != '/')$path .= '/';
	$cachefile = $path.basename($file);
	
	// 清除可能存在的缓存
	ea_clear(md5($cachefile));
	
	
	if(defined('DEBUG_PR') && DEBUG_PR == true){
		$debug_info = array(
			'trace'	=> stack_trace(),
			'file'	=> $cachefile,
			'data'	=> $array,
		);
		$GLOBALS['debug_info'][] = $debug_info;
	}
	if(defined('DEBUG_FB') && DEBUG_FB == true){
		$debug_info = empty($debug_info) ? array(
			'trace'	=> stack_trace(),
			'file'	=> $cachefile,
			'data'	=> $re,
		) : $debug_info;
		fb($debug_info, 'cache_write');
	}
	
	$strlen = file_put_contents($cachefile, $array);
	@chmod($cachefile, 0777);
	return $strlen;
}

// 生成文本文件
function cache_write_txt($file, $jsstr, $path = ''){
	if(empty($jsstr)){return false;}
	if($path == ''){$path = dirname($file);}
	if($path == '' || $path == '.'){$path = CAC_PTH;}
	if(substr($path, -1, 1) != '/')$path .= '/';
	$cachefile = $path.basename($file);
	$strlen = file_put_contents($cachefile, $jsstr);
	@chmod($cachefile, 0777);
	return $strlen;
}

function cache_delete($file, $path = ''){
	if($path == ''){$path = dirname($file);}
	if($path == '' || $path == '.'){$path = CAC_PTH;}
	if(substr($path, -1, 1) != '/')$path .= '/';
	$cachefile = $path.basename($file);
	// 清除可能存在的缓存
	$re = ea_clear(md5($cachefile));	
	if(file_exists($cachefile)){
		return @unlink($cachefile);
	}
	return true;
}

/*******************************************************************************
 * 商城配置缓存
 *******************************************************************************/
function shop_config_get($key = ''){
	$shop_config = cache_read('shop_config.php');
	if(empty($shop_config)){
		$shop_config = array();
	}
	if($key != ''){
		if(isset($shop_config[$key])){
			return $shop_config[$key];
		}
		return null;
	}
	return $shop_config;
}
function shop_config_set($key = '', $value = ''){
	if(empty($key) && empty($value)){
		return false;
	}
	$shop_config = shop_config_get();
	$shop_config[$key] = $value;
	return shop_config_save($shop_config);
}
function shop_config_save($shop_config){
	return cache_write('shop_config.php', $shop_config);
}

/********************************************************************************
* 系统方法
********************************************************************************/

// 设置 SESSION 值
function set_session($name, $value){
	$name = SESSION_PRE.$name;
	$_SESSION[$name] = $value;
}

// 获取 SESSION 值
function get_session($name){
	$name = SESSION_PRE.$name;
	if(isset($_SESSION[$name])){
		return $_SESSION[$name];
	}
	return null;
}

// 删除 SESSION
function del_session($name){
	$name = SESSION_PRE.$name;
	$_SESSION[$name] = '';
	unset($_SESSION[$name]);
}

/********************************************************************************
 * 菜单
 ********************************************************************************/


/********************************************************************************
* PHPCMS 加密函数
********************************************************************************/

function php_authcode($string, $operation = 'DECODE', $key = '', $expiry = 0){

	$ckey_length = 4; //note 随机密钥长度 取值 0-32;
	//note 加入随机密钥，可以令密文无任何规律，即便是原文和密钥完全相同，加密结果也会每次不同，增大破解难度。
	//note 取值越大，密文变动规律越大，密文变化 = 16 的 $ckey_length 次方
	//note 当此值为 0 时，则不产生随机密钥

	$key = md5($key ? $key : SITE_KEY);
	$keya = md5(substr($key, 0, 16));
	$keyb = md5(substr($key, 16, 16));
	$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';

	$cryptkey = $keya.md5($keya.$keyc);
	$key_length = strlen($cryptkey);

	$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
	$string_length = strlen($string);

	$result = '';
	$box = range(0, 255);

	$rndkey = array();
	for($i = 0; $i <= 255; $i++){
		$rndkey[$i] = ord($cryptkey[$i % $key_length]);
	}

	for($j = $i = 0; $i < 256; $i++){
		$j = ($j + $box[$i] + $rndkey[$i]) % 256;
		$tmp = $box[$i];
		$box[$i] = $box[$j];
		$box[$j] = $tmp;
	}

	for($a = $j = $i = 0; $i < $string_length; $i++){
		$a = ($a + 1) % 256;
		$j = ($j + $box[$a]) % 256;
		$tmp = $box[$a];
		$box[$a] = $box[$j];
		$box[$j] = $tmp;
		$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
	}

	if($operation == 'DECODE'){
		if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)){
			return substr($result, 26);
		} else{
			return '';
		}
	} else{
		return $keyc.str_replace('=', '', base64_encode($result));
	}
}

// 加载类名与文件名相同的类
function load($classname, $dir = '', $isinit = 1){
	
	// 此函数没有用
	
	$path = CLS_PTH.($dir ? $dir.'/' : '').$classname.'.class.php';
	if(!(@include_once $path)){
		return false;
	}
	if($isinit){
		return new $classname();
	}
	return true;
}

/********************************************************************************
 * 构造查询参数
 ********************************************************************************/

function build_queryString($opts = array()){
	if(empty($opts))return '';
	$tmp_arr = array();
	foreach($opts as $key => $val){
		$tmp_arr[] = "$key=".urlencode($val);
	}
	return implode('&', $tmp_arr);
}

function encode_queryString($opts = array(), $auth_key = '', $ttl = 300){
	if(empty($opts))return '';
	$tmp_arr = array();
	foreach($opts as $key => $val){
		$tmp_arr[] = "$key=$val";
	}
	$data = implode('&', $tmp_arr);
	$auth_key = $auth_key == '' ? EPI_KEY : $auth_key;
	if($ttl > 0){
		$encode = php_authcode($data, 'ENCODE', $auth_key, $ttl);	// 加密
	}else{
		$encode = php_authcode($data, 'ENCODE', $auth_key);	// 加密
	}
	return urlencode($encode);
}

function make_post_data($data = array(), &$post = array(), $k_pre = ''){
	if(!is_array($data) && !is_array($post))return false;
	foreach($data as $key => $val){
		$_k = $k_pre == '' ? $key : $k_pre."[{$key}]";
		if(is_array($val)){
			make_post_data($val, $post, $_k);
		}else{
			$post[$_k] = $val;
		}
	}
}

/********************************************************************************
 * 远程调用
 ********************************************************************************/
 
/*function remote_load($url, $opt_arr = array(), $varname = 'opt'){
	$queryString = "$varname=".encode_queryString($opt_arr);
	$oHttp = load('Http', 'tools');
	$r = $oHttp->post($url, $queryString);
	$data = @unserialize(trim($oHttp->data));
	
	// 调试信息
	if(defined('DEBUG_PR') && DEBUG_PR == true){		
		$GLOBALS['debug_info'][] = array(
			'trace'		=> stack_trace(),
			'opt_arr'	=> $opt_arr,
			'url'		=> $url.'?'.$queryString,
			'return'	=> $oHttp->data,
			'data'		=> $data,
		);
	}
	
	// FirePHP 调试信息
	if(defined('DEBUG_FB') && DEBUG_FB == true){
		fb(array(
			'opt_arr'	=> $opt_arr,
			'url'		=> $url.'?'.$queryString,
			'return'	=> $oHttp->data,
			'data'		=> $data,
		), 'remote_load');
	}
	
	return $data;
}*/

function curl_post($url, $fields = array(), $unserilize = false){
	$post = array();
	make_post_data($fields, $post);
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_URL, $url);			// 设定远程地址
	curl_setopt($ch, CURLOPT_POST, 1);				// post方法
	curl_setopt($ch, CURLOPT_POSTFIELDS, $post);	// 表单变量
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);	// 设定是否直接显示返回的数据
	curl_setopt($ch, CURLOPT_HEADER, false);		// 设定是否显示头信息
	curl_setopt($ch, CURLOPT_NOBODY, false);		// 设定是否直接输出页面内容 false为输出
	$return = curl_exec($ch);
	curl_errno($ch) && die(curl_error($ch));		// 出错则显示错误并退出
	curl_close($ch);// 关闭资源
	
	if($unserilize){
		$data = unserialize($return);
	}else{
		$data = $return;
	}
	
	// 调试信息
	if(defined('DEBUG_PR') && DEBUG_PR == true){
		$GLOBALS['debug_info'][] = array(
			'trace'		=> stack_trace(),
			'url'		=> $url,
			'opt_arr'	=> $fields,
			'post'		=> $post,
			'return'	=> $return,
			'data'		=> $unserilize ? $data : '',
		);
	}
	
	// FirePHP 调试信息
	if(defined('DEBUG_FB') && DEBUG_FB == true){
		fb(array(
			'url'		=> $url,
			'opt_arr'	=> $fields,
			'post'		=> $post,
			'return'	=> $return,
			'data'		=> $unserilize ? $data : '',
		), 'curl_post');
	}
	
	return $data;
}

/**
 * CURL 调用
 */
function curl_get($url, $fields = array(), $unserilize = false){
	$queryString = build_queryString($fields);
	
	$ch = curl_init();
	curl_setopt($ch, CURLOPT_REFERER, $url);
	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_POST, count($fields));
	curl_setopt($ch, CURLOPT_POSTFIELDS, $queryString);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	$return = curl_exec($ch);
	curl_close($ch);
	
	if($unserilize){
		if(!is_serialized($return)){
			return false;
		}
		try{
			$data = unserialize($return);
		}catch(Exception $e){
			return $e->getMessage();
		}
	}else{
		$data = $return;
	}

	// 调试信息
	if(defined('DEBUG_PR') && DEBUG_PR == true){
		$GLOBALS['debug_info'][] = array(
			'trace'		=> stack_trace(),
			'opt_arr'	=> $fields,
			'url'		=> $url.'?'.$queryString,
			'return'	=> $return,
			'data'		=> $unserilize ? $data : '',
		);
	}
	
	// FirePHP 调试信息
	if(defined('DEBUG_FB') && DEBUG_FB == true){
		fb(array(
			'opt_arr'	=> $fields,
			'url'		=> $url.'?'.$queryString,
			'return'	=> $return,
			'data'		=> $unserilize ? $data : '',
		), 'curl_get');
	}

	return $data;
}

// PHP CURL 下载文件
function curl_download($remote, $local){
	$cp = curl_init($remote);
	$fp = fopen($local, "w");
	curl_setopt($cp, CURLOPT_FILE, $fp);
	curl_setopt($cp, CURLOPT_HEADER, 0);
	curl_exec($cp);
	curl_close($cp);
	fclose($fp);
}

/********************************************************************************
 * 时间函数
 ********************************************************************************/

// 计算时间
function cal_time_duration($seconds = 0, $seperator = '&nbsp;'){
	$data = array();
	if($seconds >= 86400){
		$data[] = floor($seconds / 86400).'天';
		$seconds = $seconds % 86400;
	}
	if($seconds >= 3600){
		$data[] = floor($seconds / 3600).'小时';
		$seconds = $seconds % 3600;
	}
	if($seconds >= 60){
		$data[] = floor($seconds / 60).'分钟';
		$seconds = $seconds % 60;
	}
	if($seconds > 0){
		$data[] = $seconds.'秒';
	}
	return implode($seperator, $data);
}

/********************************************************************************
 * COOKIE
 ********************************************************************************/

function get_cookie($key){
	$key = COOKIE_PRE.$key;
	return isset($_COOKIE[$key]) ? $_COOKIE[$key] : false;
}

function set_cookie($key, $value, $life = 0, $httponly = false){
	if($value == '' || $life < 0){
		$value = '';
		$life = -1;
	}
	$key = COOKIE_PRE.$key;
	$timestamp = time();
	$life = $life > 0 ? $timestamp + $life : ($life < 0 ? $timestamp - 31536000 : 0);
	$path = $httponly && PHP_VERSION < '5.2.0' ? COOKIE_PTH."; HttpOnly" : COOKIE_PTH;
	$secure = $_SERVER['SERVER_PORT'] == 443 ? 1 : 0;
	if(PHP_VERSION < '5.2.0'){
		setcookie($key, $value, $life, $path, COOKIE_DOMAIN, $secure);
	} else{
		setcookie($key, $value, $life, $path, COOKIE_DOMAIN, $secure, $httponly);
	}
}



// 将时间戳转换成年、月、日路径
function time_to_path($timestamp){
	return date('Ym', $timestamp);
}

/********************************************************************************
 * 简写一些常用函数
 ********************************************************************************/

function go($url, $params = array()){
	if(!empty($params)){
		$queryString = build_queryString($params);
		$url .= (strpos($url, '?') === false ? '?' : '&').$queryString;
	}
	header('Location: '.$url);
	exit;
}

/********************************************************************************
 * 调试
 ********************************************************************************/

function stack_trace($param = true){
	$arr	= array();
	$trace	= debug_backtrace();	// print_r($trace);
	array_shift($trace);			// 第1个无意义
	foreach($trace as $pos => $row){
		$o = isset($row['class']) ? $row['class'].' -> ' : '';
		$p = array();
		if($param && !empty($row['args'])){
			foreach($row['args'] as $arg){
				if(is_array($arg)){
					$a = array();
					foreach ($arg as $key => $value){
						if(is_object($value)){
							$a[] = "'{$key}' = Object";
						}elseif(is_array($value)){
							$a[] = "'{$key}' = array(...)";
						}else{
							$a[] = "'{$key}' => '{$value}'";
						}
					}
					$p[] = 'array('.implode(', ', $a).')';
				}else{
					$p[] = "'{$arg}'";
				}
			}
		}
		$p = implode(', ', $p);
		$row['file'] = empty($row['file']) ? '' : $row['file'];
		$row['line'] = empty($row['line']) ? '' : $row['line'];
		$arr[] = $row['file']."\t# ".$row['line']."\t{$o}".$row['function']."({$p})";
	}
	$arr = array_reverse($arr);	// 用正序可能好看些
	return $arr;
}

/* 取得变量的名字 */
function get_var_name(&$src){
	// 存储当前变量值
	$save = $src;
	// 存储所有变量值
	$allvar = $GLOBALS;
	// 在函数中不要直拉遍历$GLOBALS,会出现堆栈问题
	foreach ($allvar as $k => $v){
		// 变量值相同，可能不是相同变量,因多个变量的值可能相同
		if ($src == $v){
			// 改变当前变量$src的值
			$src = 'change';
			// 如果$GLOBALS[$k]也跟着改变，那就是同一个变量。
			if ($src == $GLOBALS [$k]){
				echo "/$$k name is $k<br/>";
			}
		}
	}
	// 还原变量值
	$src = $save;
}

/********************************************************************************
 * 身份证验证
 * 15位的旧身份证,最后一个数是单数的为男，双数的为女
 * 18位的新身份证,倒数第二位是单数的为男，双数的为女
 ********************************************************************************/

// 计算身份证校验码，根据国家标准gb 11643-1999
function idcard_verify_number($idcard_base){
	if(strlen($idcard_base) != 17){
		return false;
	}
	// 加权因子
	$factor = array(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);

	// 校验码对应值
	$verify_number_list = array('1','0','X','9','8','7','6','5','4','3','2');

	$checksum = 0;
	for($i = 0; $i < strlen($idcard_base); $i++){
		$checksum += substr($idcard_base, $i, 1) * $factor [$i];
	}

	$mod = $checksum % 11;
	$verify_number = $verify_number_list [$mod];

	return $verify_number;
}

// 将15位身份证升级到18位
function idcard_15to18($idcard){
	if(strlen($idcard) != 15){
		return false;
	}else{
		// 如果身份证顺序码是996 997 998 999，这些是为百岁以上老人的特殊编码
		if(array_search(substr($idcard, 12, 3), array('996','997','998','999')) !== false){
			$idcard = substr($idcard, 0, 6) . '18' . substr($idcard, 6, 9);
		}else{
			$idcard = substr($idcard, 0, 6) . '19' . substr($idcard, 6, 9);
		}
	}
	$idcard = $idcard . idcard_verify_number($idcard);
	return $idcard;
}

// 18位身份证校验码有效性检查
function idcard_checksum18($idcard){
	if(strlen($idcard) != 18){
		return false;
	}
	$idcard_base = substr($idcard, 0, 17);
	if(idcard_verify_number($idcard_base) != strtoupper(substr($idcard, 17, 1))){
		return false;
	}else{
		return true;
	}
}

function idcard_checksum($idcard){
	if(strlen($idcard) != 18){
		$idcard = idcard_15to18($idcard);
	}
	return idcard_checksum18($idcard);
}

/********************************************************************************
 * 商品格式化
 ********************************************************************************/

function format_weight_out($weight, $unit = 'g'){
	if($unit == 'kg'){
		$weight = $weight / 1000;
	}elseif($unit == 't'){
		$weight = $weight / 1000000;
	}
	return $weight;
}

function format_weight_in($weight, $unit = 'g'){
	if($unit == 'kg'){
		$weight = $weight * 1000;
	}elseif($unit == 't'){
		$weight = $weight * 1000000;
	}
	return $weight;
}

function format_weight_kg($weight, $unit = 'g'){
	return $weight / 1000;
}

function format_delivery_date_in($type, $start = 0, $end = 0){
	if(array_key_exists($type, Statics::$delivery_date_arr)){
		if($type == 'custom'){
			$dateStr = $start.'-'.$end;
		}else{
			$dateStr = $type;
		}
		return $dateStr;
	}
	return false;
}

function format_delivery_date_out($dateStr){
	if(array_key_exists($dateStr, Statics::$delivery_date_arr)){
		return Statics::$delivery_date_arr[$dateStr];
	}
	$arr = explode('-', $dateStr);
	$str = '周'.Statics::$weekday_arr[$arr[0]];
	if(!empty($arr[1])){
		$str .= '至周'.Statics::$weekday_arr[$arr[1]];
	}
	return $str;
}

/*******************************************************************************
 * 下载文件
 *******************************************************************************/

function download($filename, $path = ''){
	if($path == '')$path = DAT_PTH;
	$wholepath = $path.$filename;
	if(!file_exists($wholepath)){
		exit('File isn\'t exist.');
	}
	if(strtolower(substr(PHP_OS, 0, 3)) == 'win'){	// 如果是Linux下，则无需转换
		$filename_encode = mb_convert_encoding($filename, 'gbk', 'utf-8');	// 避免IE下中文文件名乱码
	}else{
		$filename_encode = $filename;
	}
	header("Content-Type: application/force-download");
	header("Content-Disposition: attachment; filename={$filename_encode}");
	readfile($wholepath);
	exit;
}

/*******************************************************************************
 * 导出 CSV
 *******************************************************************************/

function export_csv($data, $headers = array(), $filename = ''){
	/*$headers = array(
		'field1'	=> '字段1',
		'field2'	=> '字段2',
		'field3'	=> '字段3',
		// ...
	);*/
	if(empty($headers)){
		$keys = array_keys($data[0]);
		$headers = array_combine($keys, $keys);
	}
	$l = array();
	foreach ($headers as $field => $title){
		if(is_array($title)){$title = $title['title'];}
		$l[] = "\"{$title}\"";
	}
	$xls = array(implode(',', $l));
	foreach($data as $key => $row){
		$l = array();
		foreach ($headers as $field => $title){
			if(is_numeric($row[$field]) && strlen($row[$field]) > 11){
				$l[] = "\"`{$row[$field]}\"";
			}else{
				$l[] = "\"".str_replace('"', '""', $row[$field])."\"";
			}
		}
		$l = implode(',', $l);
		$xls[] = $l;
	}

	$xls = mb_convert_encoding(implode("\n", $xls), 'gbk', 'utf-8');
	if(empty($filename)){$filename = 'export_'.date('Ymd_His').'.csv';}
	file_put_contents(DAT_PTH.$filename, $xls);
	// 下载
	download($filename, DAT_PTH);
}

/*******************************************************************************
 * 验证码验证，验证码由Authnum.class.php生成
 *******************************************************************************/

function authnum_check($field = 'checkcode', $type = 'post', $case = false){
	$session_name = get_session('session_name');
	del_session('session_name');	// 取出来就删除
	if(empty($session_name)){return false;}
	$session_checkcode = get_session($session_name);
	del_session($session_name);	// 取出来就删除
	if(empty($session_checkcode)){del_session($session_name); return false;}
	if($type == 'post'){
		$get_checkcode = empty($_POST[$field]) ? '' : trim($_POST[$field]);
	}else{
		$get_checkcode = empty($_GET[$field]) ? '' : trim($_GET[$field]);
	}
	if(empty($get_checkcode)){return false; }
	if(!$case){
		$session_checkcode = strtolower($session_checkcode);
		$get_checkcode = strtolower($get_checkcode);
	}
	if($get_checkcode == $session_checkcode){return true;}
	return false;
}
?>